#include "UartCmdConsole.h"
#include "serial.h"
#include <string.h>
#include <stdio.h>

// 定义最大命令长度和参数数量
#define MAX_CMD_LENGTH       128
#define MAX_ARGS             8

// 静态变量定义
static char cmdBuffer[MAX_CMD_LENGTH];
static uint16_t cmdIndex = 0;
static TaskHandle_t xConsoleTaskHandle = NULL;
static const ConsoleCommand *cmdTable = NULL;
static size_t cmdCount = 0;

// 内部函数声明
static void vConsoleTask(void *pvParameters);
static int8_t parseCommand(char *cmdLine, char *argv[]);
static void printPrompt(void);
static void processCommand(char *cmdLine);
static void helpCommand(int argc, char *argv[]);
static void echoCommand(int argc, char *argv[]);
static void versionCommand(int argc, char *argv[]);
static void rebootCommand(int argc, char *argv[]);

// 默认命令表
static const ConsoleCommand defaultCommands[] = {
    {"help",    helpCommand,    "显示可用命令列表"},
    {"version", versionCommand, "显示系统版本信息"},
    {"reboot",  rebootCommand,  "重启系统"},
    {"echo",    echoCommand,    "回显输入参数"}
};

// 帮助命令实现
static void helpCommand(int argc, char *argv[]) {
    (void)argc;
    (void)argv;
    
    Serial_printf("\r\n可用命令 (%d):\r\n", cmdCount);
    for (size_t i = 0; i < cmdCount; i++) {
        Serial_printf("  %-10s - %s\r\n", cmdTable[i].cmd, cmdTable[i].desc);
    }
    Serial_printf("\r\n");
}

// 版本命令实现
static void versionCommand(int argc, char *argv[]) {
    (void)argc;
    (void)argv;
    Serial_printf("\r\n系统版本: 1.0.0\r\n");
    Serial_printf("编译时间: %s %s\r\n\r\n", __DATE__, __TIME__);
}

// 重启命令实现
static void rebootCommand(int argc, char *argv[]) {
    (void)argc;
    (void)argv;
    Serial_printf("\r\n正在重启系统...\r\n");
    HAL_NVIC_SystemReset();
}

// 回显命令实现
static void echoCommand(int argc, char *argv[]) {
    Serial_printf("\r\n");
    for (int i = 1; i < argc; i++) {
        Serial_printf("%s ", argv[i]);
    }
    Serial_printf("\r\n\r\n");
}

// 初始化命令行控制台
void Console_Init(void) {
    // 设置默认命令表
    cmdTable = defaultCommands;
    cmdCount = sizeof(defaultCommands) / sizeof(defaultCommands[0]);
    
    // 创建控制台任务
    xTaskCreate(vConsoleTask, "Console", configMINIMAL_STACK_SIZE * 4, 
                NULL, tskIDLE_PRIORITY + 2, &xConsoleTaskHandle);
}

// 注册自定义命令
void Console_RegisterCommands(const ConsoleCommand *commands, size_t count) {
    cmdTable = commands;
    cmdCount = count;
}

// 控制台任务主函数
static void vConsoleTask(void *pvParameters) {
    (void)pvParameters;
    
    // 初始化命令缓冲区
    memset(cmdBuffer, 0, sizeof(cmdBuffer));
    cmdIndex = 0;
    
    // 显示初始提示符
    printPrompt();
    
    for (;;) {
        uint8_t ch;
        BaseType_t result;
        
        // 使用新的串口接口读取字符
        result = Serial_ReadByte(&ch, portMAX_DELAY);
        
        if (result == pdTRUE) {
            // 处理回车或换行符
            if (ch == '\r' || ch == '\n') {
                if (cmdIndex > 0) {
                    // 回显换行
                    Serial_SendString("\r\n");
                    // 处理命令
                    processCommand(cmdBuffer);
                    // 重置缓冲区
                    memset(cmdBuffer, 0, sizeof(cmdBuffer));
                    cmdIndex = 0;
                }
                printPrompt();
            }
            // 处理退格键
            else if (ch == '\b' || ch == 0x7F) {
                if (cmdIndex > 0) {
                    cmdIndex--;
                    cmdBuffer[cmdIndex] = '\0';
                    // 回显退格序列
                    Serial_SendString("\b \b");
                }
            }
            // 处理控制字符 (Ctrl+C)
            else if (ch == 0x03) {
                Serial_SendString("^C\r\n");
                memset(cmdBuffer, 0, sizeof(cmdBuffer));
                cmdIndex = 0;
                printPrompt();
            }
            // 处理可打印字符
            else if (ch >= 32 && ch <= 126) {
                if (cmdIndex < (MAX_CMD_LENGTH - 1)) {
                    cmdBuffer[cmdIndex] = ch;
                    cmdIndex++;
                    // 回显字符
                    Serial_SendData(&ch, 1);
                }
                // 缓冲区满时发出警告
                else if (cmdIndex == (MAX_CMD_LENGTH - 1)) {
                    Serial_SendString("\r\n! 命令过长，按回车执行当前命令\r\n");
                }
            }
        }
    }
}

// 解析命令行为参数数组
static int8_t parseCommand(char *cmdLine, char *argv[]) {
    int8_t argc = 0;
    char *token = strtok(cmdLine, " ");
    
    while (token != NULL && argc < MAX_ARGS) {
        argv[argc] = token;
        argc++;
        token = strtok(NULL, " ");
    }
    
    return argc;
}

// 处理命令
static void processCommand(char *cmdLine) {
    char *argv[MAX_ARGS];
    int8_t argc = parseCommand(cmdLine, argv);
    
    if (argc == 0) {
        return;
    }
    
    // 在命令表中查找匹配的命令
    for (size_t i = 0; i < cmdCount; i++) {
        if (strcmp(argv[0], cmdTable[i].cmd) == 0) {
            if (cmdTable[i].func != NULL) {
                cmdTable[i].func(argc, argv);
            } else {
                Serial_printf("命令 '%s' 未实现\r\n", argv[0]);
            }
            return;
        }
    }
    
    // 没有找到匹配的命令
    Serial_printf("未知命令: %s\r\n", argv[0]);
    Serial_printf("输入 'help' 查看可用命令\r\n");
}

// 打印提示符
static void printPrompt(void) {
    Serial_printf("\r\n> ");
}

// 控制台输出函数 (可在其他任务中使用)
void Console_Printf(const char *format, ...) {
    va_list args;
    va_start(args, format);
    
    char buffer[256];
    int len = vsnprintf(buffer, sizeof(buffer), format, args);
    
    if (len > 0) {
        Serial_SendString(buffer);
    }
    
    va_end(args);
}
